package com.learn.file.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileUtil {
    private final static Logger log = LoggerFactory.getLogger(FileUtil.class);

    public static void main(String[] args) {
        log.debug("test run");
    }

    /**
     * 功能描述: 获取文件缓存输出流
     * 文件目录，文件名
     * 不存在 该目录  直接创建,存在该文件则删除后创建
     */
    public static BufferedWriter getBufferedWriter(String diretory,String filename) {
        BufferedWriter bw = null;

        try {

            File diretoryFile = new File(diretory);
            //不存在 创建
            if (!diretoryFile.exists()) {
                diretoryFile.mkdirs();
            }
            //
            File currentFile = new File(diretory, filename);
            if (currentFile.exists()) {
                currentFile.delete();
            }
            currentFile.createNewFile();

            bw = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(diretory + "/" + filename), "UTF-8"));

        } catch (Exception var7) {
            log.error(var7.getMessage());
        }

        return bw;
    }

    /**
     * 功能描述:使用缓存写入流 写入文件
     */
    public static void writeToFile(BufferedWriter bw, String content) {
        try {
            bw.write(content);
            bw.flush();
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }

    /**
     * 功能描述:关闭缓存写入流
     */
    public static void closeBufferedWriter(BufferedWriter bw) {
        try {
            if (bw != null) {
                bw.close();
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 功能描述:文件复制
     * 需要复制的文件，复制文件存储目录
     */
    public static void copyFile(File file, String diretory) {
        FileChannel in = null;
        FileChannel out = null;
        File copyFile = null;

        try {
            copyFile = new File(diretory, file.getName());
            in = (new FileInputStream(file)).getChannel();
            out = (new FileOutputStream(copyFile)).getChannel();
            out.transferFrom(in, 0L, in.size());
        } catch (Exception e) {
            log.error("复制文件出错!");
        } finally {
            try {
                if (in != null) {
                    in.close();
                }

                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                log.error(e.getMessage());
            }

        }

    }

    /**
     * 功能描述:文件压缩
     *
     */
    public static File createZip(File[] files, String filename, String directory) throws Exception {
        short s = 8192;
        FileInputStream inputStream = null;
        ZipOutputStream zipOutputStream = null;
        File zipOutFile = new File(directory + File.separator + filename);
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;

        try {
            fileOutputStream = new FileOutputStream(zipOutFile);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            zipOutputStream = new ZipOutputStream(bufferedOutputStream);

            File[] fileArray = files;
            int size = fileArray.length;

            for(int i = 0; i < size; ++i) {
                File file = fileArray[i];
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                inputStream = new FileInputStream(file);
                byte[] bytes = new byte[s];

                int read;
                while((read = inputStream.read(bytes)) != -1) {
                    zipOutputStream.write(bytes, 0, read);
                }

                inputStream.close();
            }
        } catch (Exception e) {
            throw new Exception("生成ZIP文件错误:[" + e.getMessage() + "]");
        } finally {
            if (zipOutputStream != null) {
                zipOutputStream.close();
            }

            if (fileOutputStream != null) {
                fileOutputStream.close();
            }

            if (inputStream != null) {
                inputStream.close();
            }

        }

        return zipOutFile;
    }

    /**
     * 功能描述:删除指定文件
     */
    public static Boolean deleteFile(String file) {
        try {
            if (file != null) {
                File target = new File(file);
                if (target.exists() && target.isFile()) {
                    return target.delete();
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return false;
    }

    /**
     * 功能描述:删除指定目录
     */
    public static boolean delFolder(String directory) {
        boolean flag = false;

        try {
            //删除指定目录下所有文件
            delAllFilesByDir(directory);
            //删除目录
            File directoryFile = new File(directory);
            directoryFile.delete();
            if (!directoryFile.exists()) {
                flag = true;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return flag;
    }

    public static boolean delAllFilesByDir(String directory) {
        boolean flag = false;
        File targetDirectoryFile = new File(directory);
        if (!targetDirectoryFile.exists()) {
            flag = true;
        } else {
            String[] files = targetDirectoryFile.list();
            File file = null;

            for(int i = 0; i < files.length; ++i) {

                if (directory.endsWith(File.separator)) {
                    file = new File(directory + files[i]);
                } else {
                    file = new File(directory + File.separator + files[i]);
                }

                if (file.isFile()) {
                    file.delete();
                }

                if (file.isDirectory()) {
                    delAllFilesByDir(file.getAbsolutePath());
                    delFolder(file.getAbsolutePath());
                }
            }
        }

        return flag;
    }

}
